/*
 * Copyright (c) 2023-2024 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.controller;

import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elsfs.cloud.common.core.vo.R;
import org.elsfs.cloud.common.entity.DuplicateCheckQry;
import org.elsfs.cloud.common.entity.DuplicateCheckVO;
import org.elsfs.cloud.common.util.exception.QueryException;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * 重复校验工具
 *
 * @author zeng
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/duplicate")
@Tag(description = "duplicate", name = "重复校验")
public class DuplicateCheckController {

  private final ObjectProvider<JdbcTemplate> templateObjectProvider;

  /**
   * 校验数据是否在系统中是否存在
   *
   * @return r
   */
  @RequestMapping(value = "/check", method = RequestMethod.GET)
  @Operation(summary = "重复校验接口")
  public R<DuplicateCheckVO> doDuplicateCheck(
      @ParameterObject @Validated DuplicateCheckQry qry, HttpServletRequest request) {
    LOGGER.debug("----duplicate check------：{}", qry.toString());

    // 1.填值为空，直接返回
    if (!StringUtils.hasText(qry.getFieldVal())) {

      return R.success(new DuplicateCheckVO().setPass(true)).setMessage("数据为空,不作处理");
    }
    boolean checkData = duplicateCheckData(qry);
    // true  该值可用   false 该值不可用
    return R.success(
        new DuplicateCheckVO()
            .setPass(checkData)
            .setMessage(checkData ? "该值可用，可进行操作！" : "该值不可用，系统中已存在！"));
  }

  /**
   * 校验数据是否在系统中是否存在
   *
   * @param qry 查询参数
   * @return boolean
   */
  public boolean duplicateCheckData(DuplicateCheckQry qry) {
    Long count = null;
    String table = "`" + qry.getSchemaName() + "`." + qry.getTableName();
    if (SqlInjectionUtils.check(table) || SqlInjectionUtils.check(qry.getKeyName())) {
      throw new QueryException("表名或字段名包含非法字符！");
    }

    String addCheckSql =
        String.format(
            "SELECT  COUNT(1) FROM %s  WHERE %s=?  and delete_flag = 0 ",
            table, qry.getFieldName());
    String editCheckSql = String.format(addCheckSql + " AND %s<> ?", qry.getKeyName());
    // 4.执行SQL 查询是否存在值
    try {
      if (StringUtils.hasText(qry.getDataId())) {
        // [1].编辑页面校验
        count =
            getJdbcTemplate()
                .queryForObject(editCheckSql, Long.class, qry.getFieldVal(), qry.getDataId());
        // 4.返回结果
        return count == null || count == 0;
      } else {
        // [2].添加页面校验
        count = getJdbcTemplate().queryForObject(addCheckSql, Long.class, qry.getFieldVal());
        return count == null || count == 0;
      }
    } catch (QueryException e) {
      LOGGER.error(e.getMessage(), e);
      throw new QueryException("查询异常,请检查唯一校验的配置！");
    }
  }

  private JdbcTemplate getJdbcTemplate() {
    JdbcTemplate jdbcTemplate = templateObjectProvider.getIfAvailable();
    if (jdbcTemplate == null) {
      throw new QueryException("dbcTemplate is null");
    }
    return jdbcTemplate;
  }
}
